package laan.data.requestcenter
{
    import flash.events.*;
    import flash.net.*;
    import flash.utils.*;

    public class RequestCenter extends EventDispatcher implements IRequestCenter
    {
        private var requestQueue:Array;
        private var _delay:uint = 3000;
        private var _isRequesting:Boolean = false;
        private var tokenMap:Object;
        private var requestingMap:Dictionary;
        private var _requestType:String;
        private var requestTimer:Timer;

        public function RequestCenter(type:String = "subsequent")
        {
            tokenMap = new Object();
            requestQueue = new Array();
            requestingMap = new Dictionary(true);
            requestType = type;
            return;
        }// end function

        private function removeLoaderHandlers(loader:URLLoader) : void
        {
            delete requestingMap[loader];
            loader.removeEventListener(Event.COMPLETE, completeHandler);
            loader.removeEventListener(Event.OPEN, openHandler);
            loader.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
            loader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            loader.removeEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
            loader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            return;
        }// end function

        public function get delay() : uint
        {
            return _delay;
        }// end function

        private function doResult(loader:TokenLoader) : void
        {
            var _loc_4:Function = null;
            trace("realToken:" + loader.token);
            trace("data:" + loader.data);
            trace("---------------------------------------------------\r\r");
            _isRequesting = false;
            var _loc_2:* = loader.token;
            var _loc_3:* = loader.data;
            if (tokenMap[_loc_2] != null)
            {
                _loc_4 = tokenMap[_loc_2] as Function;
                _loc_4.call(null, new TokenData(_loc_2, _loc_3, loader.request));
                delete tokenMap[_loc_2];
            }
            if (_requestType == RequestType.QUEUE)
            {
                doNextRequest();
            }
            return;
        }// end function

        private function securityErrorHandler(event:SecurityErrorEvent) : void
        {
            var _loc_2:* = event.target as TokenLoader;
            removeLoaderHandlers(_loc_2);
            trace("securityErrorHandler: " + _loc_2.request.url);
            doResult(_loc_2);
            dispatchEvent(new RequestEvent(RequestEvent.FAILED, _loc_2));
            return;
        }// end function

        private function doRequest() : void
        {
            switch(_requestType)
            {
                case RequestType.QUEUE:
                {
                    if (!_isRequesting)
                    {
                        doNextRequest();
                    }
                    break;
                }
                case RequestType.TIMER:
                {
                    if (!requestTimer.running)
                    {
                        requestTimer.start();
                    }
                    break;
                }
                case RequestType.SUBSEQUENT:
                {
                    while (requestQueue.length != 0)
                    {
                        
                        doNextRequest();
                    }
                    break;
                }
                default:
                {
                    break;
                }
            }
            return;
        }// end function

        public function set delay(value:uint) : void
        {
            if (_delay == value)
            {
                return;
            }
            _delay = value;
            if (_requestType == RequestType.TIMER)
            {
                if (requestTimer)
                {
                    requestTimer.removeEventListener(TimerEvent.TIMER, requestTimerHandler);
                    requestTimer.stop();
                }
                requestTimer = new Timer(_delay);
                requestTimer.addEventListener(TimerEvent.TIMER, requestTimerHandler);
                requestTimer.start();
            }
            return;
        }// end function

        private function httpStatusHandler(event:HTTPStatusEvent) : void
        {
            return;
        }// end function

        private function doNextRequest() : void
        {
            if (requestQueue.length == 0)
            {
                if (_requestType == RequestType.TIMER)
                {
                    requestTimer.stop();
                }
                return;
            }
            var _loc_1:* = requestQueue.shift() as TokenLoader;
            addLoaderHandlers(_loc_1);
            _loc_1.load(_loc_1.request);
            _isRequesting = true;
            dispatchEvent(new RequestEvent(RequestEvent.REQUEST_START, _loc_1));
            return;
        }// end function

        private function completeHandler(event:Event) : void
        {
            var _loc_2:* = event.target as TokenLoader;
            removeLoaderHandlers(_loc_2);
            trace("request complet:" + _loc_2.request.url);
            doResult(_loc_2);
            dispatchEvent(new RequestEvent(RequestEvent.COMPLETE, _loc_2));
            return;
        }// end function

        public function set requestType(value:String) : void
        {
            if (value != RequestType.QUEUE)
            {
            }
            if (value != RequestType.SUBSEQUENT)
            {
            }
            if (value != RequestType.TIMER)
            {
                value = RequestType.SUBSEQUENT;
            }
            if (_requestType == value)
            {
                return;
            }
            _requestType = value;
            if (_requestType == RequestType.TIMER)
            {
            }
            if (!requestTimer)
            {
                requestTimer = new Timer(_delay);
                requestTimer.addEventListener(TimerEvent.TIMER, requestTimerHandler);
            }
            else if (requestTimer)
            {
                requestTimer.stop();
                requestTimer.removeEventListener(TimerEvent.TIMER, requestTimerHandler);
                requestTimer = null;
            }
            doRequest();
            dispatchEvent(new RequestEvent(RequestEvent.REQUEST_TYPE_CHANGE));
            return;
        }// end function

        public function releaseAll() : void
        {
            var i:Object;
            var loader:URLLoader;
            requestQueue = [];
            if (_requestType == RequestType.TIMER)
            {
                requestTimer.stop();
            }
            var _loc_2:int = 0;
            var _loc_3:* = requestingMap;
            while (_loc_3 in _loc_2)
            {
                
                i = _loc_3[_loc_2];
                loader = i as URLLoader;
                try
                {
                    loader.close();
                }
                catch (e:Error)
                {
                }
                removeLoaderHandlers(loader);
            }
            return;
        }// end function

        private function addLoaderHandlers(loader:URLLoader) : void
        {
            requestingMap[loader] = true;
            loader.addEventListener(Event.COMPLETE, completeHandler);
            loader.addEventListener(Event.OPEN, openHandler);
            loader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
            loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
            loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
            loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
            return;
        }// end function

        private function openHandler(event:Event) : void
        {
            return;
        }// end function

        private function progressHandler(event:ProgressEvent) : void
        {
            return;
        }// end function

        private function ioErrorHandler(event:IOErrorEvent) : void
        {
            var _loc_2:* = event.target as TokenLoader;
            removeLoaderHandlers(_loc_2);
            trace("ioErrorHandler: " + _loc_2.request.url);
            doResult(_loc_2);
            dispatchEvent(new RequestEvent(RequestEvent.FAILED, _loc_2));
            return;
        }// end function

        public function get requestType() : String
        {
            return _requestType;
        }// end function

        public function releaseToken(token:String) : void
        {
            var _loc_4:TokenLoader = null;
            var _loc_2:* = requestQueue.length;
            var _loc_3:uint = 0;
            while (_loc_3 < _loc_2)
            {
                
                _loc_4 = requestQueue[_loc_3];
                if (_loc_4.token == token)
                {
                    requestQueue.splice(_loc_3, 1);
                    break;
                }
                _loc_3 = _loc_3 + 1;
            }
            return;
        }// end function

        private function requestTimerHandler(event:TimerEvent) : void
        {
            doNextRequest();
            return;
        }// end function

        public function addRequest(request:URLRequest, handler:Function, token:String = null, binary:Boolean = false) : void
        {
            if (!token)
            {
                token = request.url + "_" + Math.random();
            }
            if (tokenMap[token])
            {
                throw new Error("The request pointed by token:" + token + " has exist!");
            }
            tokenMap[token] = handler;
            var _loc_5:* = new TokenLoader(token, request);
            if (binary)
            {
                _loc_5.dataFormat = URLLoaderDataFormat.BINARY;
            }
            requestQueue.push(_loc_5);
            doRequest();
            dispatchEvent(new RequestEvent(RequestEvent.REQEUST_ADD, {request:request, handler:handler, token:token, binary:binary}));
            return;
        }// end function

        public function get isRequesting() : Boolean
        {
            return _isRequesting;
        }// end function

    }
}
